package com.xhx.moduledevelop.springspi;

import java.util.List;
import java.util.Map;

import org.redisson.spring.starter.RedissonAutoConfiguration;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.io.support.SpringFactoriesLoader;

import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
import com.xhx.moduledevelop.MessagePlugin;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@SpringBootApplication(scanBasePackages = "com.xhx.moduledevelop", exclude = { RedissonAutoConfiguration.class,
		RedisAutoConfiguration.class, MybatisPlusAutoConfiguration.class, DataSourceAutoConfiguration.class })
public class SpringSpiTest {

	public static void main(String[] args) {
		// 需要配置/META-INF/spring.factories
		SpringApplication application = new SpringApplication(SpringSpiTest.class);
		// 非web方式启动
		application.setWebApplicationType(WebApplicationType.NONE);
		ConfigurableApplicationContext context = application.run(args);
		log.info("spi执行");
		List<MessagePlugin> plugins = SpringFactoriesLoader.loadFactories(MessagePlugin.class, null);
		for (MessagePlugin plugin : plugins) {
			plugin.send(null);
			registe(context, plugin);
		}

		log.info("容器中执行");
		Map<String, MessagePlugin> map = context.getBeansOfType(MessagePlugin.class);
		map.forEach((k, v) -> {
			log.info("name:{},class:{}", k, v.getClass().getSimpleName());
			v.send(null);
		});

	}

	/**
	 * 手动注入到容器
	 * 
	 * @param context
	 * @param bean
	 */
	static void registe(ConfigurableApplicationContext context, MessagePlugin bean) {
		AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(bean.getClass())
				.getBeanDefinition();
		BeanDefinitionRegistry registry = (BeanDefinitionRegistry) context.getBeanFactory();
		registry.registerBeanDefinition(bean.getClass().getSimpleName(), beanDefinition);
	}

}
